// 流式输出 streamText
// AI SDK 中用于生成流式文本响应的核心函数，支持逐字输出、工具调用和异步处理
import {
  embed,
  streamText
} from 'ai';
import {
  createOpenAI
} from '@ai-sdk/openai';
import {
  createClient
} from '@supabase/supabase-js';

const supabase = createClient(
  process.env.SUPABASE_URL ?? "",
  process.env.SUPABASE_KEY ?? ""
);

const openai = createOpenAI({
  apiKey: process.env.OPENAI_API_KEY,
  baseURL: process.env.OPENAI_API_BASE_URL,
});

async function generateEmbedding(message: string) {
  return await embed({
    model: openai.embedding('text-embedding-3-small'),
    value: message
  });
}

async function fetchRelevantContext(embedding: number[]) {
  const { data, error } = await supabase.rpc("get_relevant_chunks", {
    query_vector: embedding,
    match_threshold: 0.4,
    match_count: 3,
  });
  if (error) throw error;
  return JSON.stringify(
    data.map((item:any) => `
      Source: ${item.url},
      Date Updated: ${item.date_updated},
      Content: ${item.content}
    `)
  );
}

const createPrompt = (context: string, userQuestion: string) => {
  return {
    role: 'system',
    content: `
      You are a specialized assistant named "罗德岛战术助手" (Rhodes Island Tactical Assistant), designed to provide accurate information about the mobile game "Arknights" (明日方舟). 
      Use the following context from the PRTS Wiki to answer questions: 
      ----------------
      START CONTEXT
      ${context}
      END CONTEXT
      ----------------

      Return the answer in markdown format including relevant details such as:
      - Character skills and talents
      - Item acquisition methods  
      - Stage strategies and enemy data
      - Story and lore explanations
      - Include the date when the information was last updated from the source.

      Where the above context does not provide enough information relating to the question, provide an answer based on your own knowledge but clearly state that this information may not be current or fully accurate.

      If the user asks a question that is not related to Arknights, politely inform them that you can only answer questions about the Arknights universe, including:
      - Operator information and builds
      - Stage guides and event content
      - Game mechanics and items
      - Worldview and story lore

      ----------------
      QUESTION: ${userQuestion}
      ----------------
    `,
  }
}

export async function POST(req: Request) {
  try {
    const { messages } = await req.json();
    const latestMessage = messages.at(-1).content;
    // embedding
    const { embedding } = await generateEmbedding(latestMessage);
    // 相似度计算
    const context = await fetchRelevantContext(embedding);
    console.log(context);
    const prompt = createPrompt(context, latestMessage);
    const result = streamText({
      model: openai.chat('gpt-4o-mini'),
      messages: [prompt, ...messages],
    })
    return result.toDataStreamResponse();
  } catch (error) {
    throw error;
  }
}